I. Preliminaries

Loading libraries

library("tidyverse")
library("tibble")
library("msigdbr")
library("ggplot2")
library("ensembldb")
library("purrr")
library("magrittr")
library("matrixStats")
library("dplyr")
library("grex")
library("gplots")
library("RColorBrewer")
library("illuminaHumanv4.db")

Constants

DATA_DIR <- "../data/public/GEO/HDFn/"

Loading the Expression Data

The expression data are taken from this study: https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE84144

Download the RNA-seq normalized counts matrices (one matrix per replicate) from: - https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSM2227697 - https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSM2227698 - https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSM2227699

hdfn.expression1 <- read.delim(paste0(DATA_DIR, "GSE84144-hdfn-1.tsv"), as.is = TRUE, header = TRUE, row.names = 1)
hdfn.expression1 <- rownames_to_column(hdfn.expression1, "ID_REF")
hdfn.expression1 <- hdfn.expression1[c("ID_REF", "VALUE")]

hdfn.expression2 <- read.delim(paste0(DATA_DIR, "GSE84144-hdfn-2.tsv"), as.is = TRUE, header = TRUE, row.names = 1)
hdfn.expression2 <- rownames_to_column(hdfn.expression2, "ID_REF")
hdfn.expression2 <- hdfn.expression2[c("ID_REF", "VALUE")]

hdfn.expression3 <- read.delim(paste0(DATA_DIR, "GSE84144-hdfn-3.tsv"), as.is = TRUE, header = TRUE, row.names = 1)
hdfn.expression3 <- rownames_to_column(hdfn.expression3, "ID_REF")
hdfn.expression3 <- hdfn.expression3[c("ID_REF", "VALUE")]

hdfn.expression3

Merge the gene expression data for the three replicates into one data frame.

hdfn.expression <- left_join(hdfn.expression1, hdfn.expression2, join_by(ID_REF))
hdfn.expression <- left_join(hdfn.expression, hdfn.expression3, join_by(ID_REF))
hdfn.expression <- hdfn.expression %>% rename("VALUE.x" = "Replicate 1", "VALUE.y" = "Replicate 2", "VALUE" = "Replicate 3")
hdfn.expression

Map the Illumina probe IDs to Ensembl accessions.

illumina_to_ensembl = data.frame(gene_id=unlist(mget(x = hdfn.expression[["ID_REF"]], envir = illuminaHumanv4ENSEMBL)))
illumina_to_ensembl <- rownames_to_column(illumina_to_ensembl, "ID_REF")
illumina_to_ensembl
hdfn.expression <- left_join(hdfn.expression, illumina_to_ensembl)
Joining with `by = join_by(ID_REF)`
hdfn.expression

Exploratory Data Analysis

We load the gene sets from RCDdb: https://pubmed.ncbi.nlm.nih.gov/39257527/

RCDdb <- "../data/public/rcd-gene-list/RCDdb/"

Necroptosis

Load the gene set.

genes <- read.csv(paste0(RCDdb, "Necroptosis.csv"))
genes$gene_id <- cleanid(genes$gene_id)
genes <- distinct(genes, gene_id, .keep_all = TRUE)
genes <- subset(genes, gene_id != "")
genes

Get the normalized expression data for the genes in the gene set.

tpm.df <- hdfn.expression %>% dplyr::filter(gene_id %in% genes$gene_id)
tpm.df <- left_join(tpm.df, genes %>% dplyr::select(gene_id, gene), by = c("gene_id" = "gene_id"))
tpm.df <- distinct(tpm.df, gene, .keep_all = TRUE)
rownames(tpm.df) <- tpm.df$gene
tpm.df <- subset(tpm.df, select = -c(gene_id, ID_REF, gene) )
tpm.df <- tpm.df[ order(row.names(tpm.df)), , drop = FALSE]
tpm.df

Plot the results.

tpm.matrix <- as.matrix(tpm.df)
heatmap.2(tpm.matrix, srtCol=360, cellnote = tpm.matrix, dendrogram="none", Colv=FALSE, Rowv=FALSE,
          col=brewer.pal(n = 9, name = "BuPu")[5:9], trace="none", key = FALSE, lwid=c(0.1,4), lhei=c(0.1,4),
          cexCol=1, cexRow=0.75, symm = TRUE)

Ferroptosis

Load the gene set.

genes <- read.csv(paste0(RCDdb, "Ferroptosis.csv"))
genes$gene_id <- cleanid(genes$gene_id)
genes <- distinct(genes, gene_id, .keep_all = TRUE)
genes <- subset(genes, gene_id != "")
genes

Get the normalized expression data for the genes in the gene set.

tpm.df <- hdfn.expression %>% dplyr::filter(gene_id %in% genes$gene_id)
tpm.df <- left_join(tpm.df, genes %>% dplyr::select(gene_id, gene), by = c("gene_id" = "gene_id"))
tpm.df <- distinct(tpm.df, gene, .keep_all = TRUE)
rownames(tpm.df) <- tpm.df$gene
tpm.df <- subset(tpm.df, select = -c(gene_id, ID_REF, gene) )
tpm.df <- tpm.df[ order(row.names(tpm.df)), , drop = FALSE]
tpm.df

Plot the results.

tpm.matrix <- as.matrix(tpm.df)
heatmap.2(tpm.matrix, srtCol=360, cellnote = tpm.matrix, dendrogram="none", Colv=FALSE, Rowv=FALSE,
          col=brewer.pal(n = 9, name = "BuPu")[5:9], trace="none", key = FALSE, lwid=c(0.1,4), lhei=c(0.1,4),
          cexCol=1, cexRow=0.75, symm = TRUE)

Pyroptosis

Load the gene set.

genes <- read.csv(paste0(RCDdb, "Pyroptosis.csv"))
genes$gene_id <- cleanid(genes$gene_id)
genes <- distinct(genes, gene_id, .keep_all = TRUE)
genes <- subset(genes, gene_id != "")
genes

Get the normalized expression data for the genes in the gene set.

tpm.df <- hdfn.expression %>% dplyr::filter(gene_id %in% genes$gene_id)
tpm.df <- left_join(tpm.df, genes %>% dplyr::select(gene_id, gene), by = c("gene_id" = "gene_id"))
tpm.df <- distinct(tpm.df, gene, .keep_all = TRUE)
rownames(tpm.df) <- tpm.df$gene
tpm.df <- subset(tpm.df, select = -c(gene_id, ID_REF, gene) )
tpm.df <- tpm.df[ order(row.names(tpm.df)), , drop = FALSE]
tpm.df

Plot the results.

tpm.matrix <- as.matrix(tpm.df)
heatmap.2(tpm.matrix, srtCol=360, cellnote = tpm.matrix, dendrogram="none", Colv=FALSE, Rowv=FALSE,
          col=brewer.pal(n = 9, name = "BuPu")[5:9], trace="none", key = FALSE, lwid=c(0.1,4), lhei=c(0.1,4),
          cexCol=1, cexRow=0.75, symm = TRUE)


  1. De La Salle University, Manila, Philippines, ↩︎

  2. De La Salle University, Manila, Philippines, ↩︎

LS0tDQp0aXRsZTogIkdlbmUgRXhwcmVzc2lvbiBBbmFseXNpcyINCnN1YnRpdGxlOiAiSHVtYW4gRGVybWFsIEZpYnJvYmxhc3RzLCBuZW9uYXRhbCAoSERGbikgfCBHU0U4NDE0NCB8IE5lY3JvcHRvc2lzLCBGZXJyb3B0b3NpcyAmIFB5cm9wdG9zaXMiDQphdXRob3I6IA0KICAtIE1hcmsgRWR3YXJkIE0uIEdvbnphbGVzXltEZSBMYSBTYWxsZSBVbml2ZXJzaXR5LCBNYW5pbGEsIFBoaWxpcHBpbmVzLCBnb256YWxlcy5tYXJrZWR3YXJkQGdtYWlsLmNvbV0NCiAgLSBEci4gQW5pc2ggTS5TLiBTaHJlc3RoYV5bRGUgTGEgU2FsbGUgVW5pdmVyc2l0eSwgTWFuaWxhLCBQaGlsaXBwaW5lcywgYW5pc2guc2hyZXN0aGFAZGxzdS5lZHUucGhdDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIyBJLiBQcmVsaW1pbmFyaWVzDQoNCiMjIyBMb2FkaW5nIGxpYnJhcmllcw0KDQpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCmxpYnJhcnkoInRpZHl2ZXJzZSIpDQpsaWJyYXJ5KCJ0aWJibGUiKQ0KbGlicmFyeSgibXNpZ2RiciIpDQpsaWJyYXJ5KCJnZ3Bsb3QyIikNCmxpYnJhcnkoImVuc2VtYmxkYiIpDQpsaWJyYXJ5KCJwdXJyciIpDQpsaWJyYXJ5KCJtYWdyaXR0ciIpDQpsaWJyYXJ5KCJtYXRyaXhTdGF0cyIpDQpsaWJyYXJ5KCJkcGx5ciIpDQpsaWJyYXJ5KCJncmV4IikNCmxpYnJhcnkoImdwbG90cyIpDQpsaWJyYXJ5KCJSQ29sb3JCcmV3ZXIiKQ0KbGlicmFyeSgiaWxsdW1pbmFIdW1hbnY0LmRiIikNCmBgYA0KDQojIyMgQ29uc3RhbnRzDQpgYGB7cn0NCkRBVEFfRElSIDwtICIuLi9kYXRhL3B1YmxpYy9HRU8vSERGbi8iDQpgYGANCg0KIyMgTG9hZGluZyB0aGUgRXhwcmVzc2lvbiBEYXRhDQoNClRoZSBleHByZXNzaW9uIGRhdGEgYXJlIHRha2VuIGZyb20gdGhpcyBzdHVkeTogaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9nZW8vcXVlcnkvYWNjLmNnaT9hY2M9R1NFODQxNDQNCg0KRG93bmxvYWQgdGhlIFJOQS1zZXEgbm9ybWFsaXplZCBjb3VudHMgbWF0cmljZXMgKG9uZSBtYXRyaXggcGVyIHJlcGxpY2F0ZSkgZnJvbToNCi0gaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9nZW8vcXVlcnkvYWNjLmNnaT9hY2M9R1NNMjIyNzY5Nw0KLSBodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L2dlby9xdWVyeS9hY2MuY2dpP2FjYz1HU00yMjI3Njk4DQotIGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvZ2VvL3F1ZXJ5L2FjYy5jZ2k/YWNjPUdTTTIyMjc2OTkNCg0KYGBge3J9DQpoZGZuLmV4cHJlc3Npb24xIDwtIHJlYWQuZGVsaW0ocGFzdGUwKERBVEFfRElSLCAiR1NFODQxNDQtaGRmbi0xLnRzdiIpLCBhcy5pcyA9IFRSVUUsIGhlYWRlciA9IFRSVUUsIHJvdy5uYW1lcyA9IDEpDQpoZGZuLmV4cHJlc3Npb24xIDwtIHJvd25hbWVzX3RvX2NvbHVtbihoZGZuLmV4cHJlc3Npb24xLCAiSURfUkVGIikNCmhkZm4uZXhwcmVzc2lvbjEgPC0gaGRmbi5leHByZXNzaW9uMVtjKCJJRF9SRUYiLCAiVkFMVUUiKV0NCg0KaGRmbi5leHByZXNzaW9uMiA8LSByZWFkLmRlbGltKHBhc3RlMChEQVRBX0RJUiwgIkdTRTg0MTQ0LWhkZm4tMi50c3YiKSwgYXMuaXMgPSBUUlVFLCBoZWFkZXIgPSBUUlVFLCByb3cubmFtZXMgPSAxKQ0KaGRmbi5leHByZXNzaW9uMiA8LSByb3duYW1lc190b19jb2x1bW4oaGRmbi5leHByZXNzaW9uMiwgIklEX1JFRiIpDQpoZGZuLmV4cHJlc3Npb24yIDwtIGhkZm4uZXhwcmVzc2lvbjJbYygiSURfUkVGIiwgIlZBTFVFIildDQoNCmhkZm4uZXhwcmVzc2lvbjMgPC0gcmVhZC5kZWxpbShwYXN0ZTAoREFUQV9ESVIsICJHU0U4NDE0NC1oZGZuLTMudHN2IiksIGFzLmlzID0gVFJVRSwgaGVhZGVyID0gVFJVRSwgcm93Lm5hbWVzID0gMSkNCmhkZm4uZXhwcmVzc2lvbjMgPC0gcm93bmFtZXNfdG9fY29sdW1uKGhkZm4uZXhwcmVzc2lvbjMsICJJRF9SRUYiKQ0KaGRmbi5leHByZXNzaW9uMyA8LSBoZGZuLmV4cHJlc3Npb24zW2MoIklEX1JFRiIsICJWQUxVRSIpXQ0KDQpoZGZuLmV4cHJlc3Npb24zDQpgYGANCg0KTWVyZ2UgdGhlIGdlbmUgZXhwcmVzc2lvbiBkYXRhIGZvciB0aGUgdGhyZWUgcmVwbGljYXRlcyBpbnRvIG9uZSBkYXRhIGZyYW1lLg0KDQpgYGB7cn0NCmhkZm4uZXhwcmVzc2lvbiA8LSBsZWZ0X2pvaW4oaGRmbi5leHByZXNzaW9uMSwgaGRmbi5leHByZXNzaW9uMiwgam9pbl9ieShJRF9SRUYpKQ0KaGRmbi5leHByZXNzaW9uIDwtIGxlZnRfam9pbihoZGZuLmV4cHJlc3Npb24sIGhkZm4uZXhwcmVzc2lvbjMsIGpvaW5fYnkoSURfUkVGKSkNCmhkZm4uZXhwcmVzc2lvbiA8LSBoZGZuLmV4cHJlc3Npb24gJT4lIHJlbmFtZSgiVkFMVUUueCIgPSAiUmVwbGljYXRlIDEiLCAiVkFMVUUueSIgPSAiUmVwbGljYXRlIDIiLCAiVkFMVUUiID0gIlJlcGxpY2F0ZSAzIikNCmhkZm4uZXhwcmVzc2lvbg0KYGBgDQoNCk1hcCB0aGUgSWxsdW1pbmEgcHJvYmUgSURzIHRvIEVuc2VtYmwgYWNjZXNzaW9ucy4NCg0KYGBge3J9DQppbGx1bWluYV90b19lbnNlbWJsID0gZGF0YS5mcmFtZShnZW5lX2lkPXVubGlzdChtZ2V0KHggPSBoZGZuLmV4cHJlc3Npb25bWyJJRF9SRUYiXV0sIGVudmlyID0gaWxsdW1pbmFIdW1hbnY0RU5TRU1CTCkpKQ0KaWxsdW1pbmFfdG9fZW5zZW1ibCA8LSByb3duYW1lc190b19jb2x1bW4oaWxsdW1pbmFfdG9fZW5zZW1ibCwgIklEX1JFRiIpDQppbGx1bWluYV90b19lbnNlbWJsDQpgYGANCg0KYGBge3J9DQpoZGZuLmV4cHJlc3Npb24gPC0gbGVmdF9qb2luKGhkZm4uZXhwcmVzc2lvbiwgaWxsdW1pbmFfdG9fZW5zZW1ibCkNCmhkZm4uZXhwcmVzc2lvbg0KYGBgDQoNCiMjIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMNCg0KV2UgbG9hZCB0aGUgZ2VuZSBzZXRzIGZyb20gUkNEZGI6IGh0dHBzOi8vcHVibWVkLm5jYmkubmxtLm5paC5nb3YvMzkyNTc1MjcvDQoNCmBgYHtyfQ0KUkNEZGIgPC0gIi4uL2RhdGEvcHVibGljL3JjZC1nZW5lLWxpc3QvUkNEZGIvIg0KYGBgDQoNCiMjIyBOZWNyb3B0b3Npcw0KDQpMb2FkIHRoZSBnZW5lIHNldC4NCg0KYGBge3J9DQpnZW5lcyA8LSByZWFkLmNzdihwYXN0ZTAoUkNEZGIsICJOZWNyb3B0b3Npcy5jc3YiKSkNCmdlbmVzJGdlbmVfaWQgPC0gY2xlYW5pZChnZW5lcyRnZW5lX2lkKQ0KZ2VuZXMgPC0gZGlzdGluY3QoZ2VuZXMsIGdlbmVfaWQsIC5rZWVwX2FsbCA9IFRSVUUpDQpnZW5lcyA8LSBzdWJzZXQoZ2VuZXMsIGdlbmVfaWQgIT0gIiIpDQpnZW5lcw0KYGBgDQoNCkdldCB0aGUgbm9ybWFsaXplZCBleHByZXNzaW9uIGRhdGEgZm9yIHRoZSBnZW5lcyBpbiB0aGUgZ2VuZSBzZXQuDQoNCmBgYHtyfQ0KdHBtLmRmIDwtIGhkZm4uZXhwcmVzc2lvbiAlPiUgZHBseXI6OmZpbHRlcihnZW5lX2lkICVpbiUgZ2VuZXMkZ2VuZV9pZCkNCnRwbS5kZiA8LSBsZWZ0X2pvaW4odHBtLmRmLCBnZW5lcyAlPiUgZHBseXI6OnNlbGVjdChnZW5lX2lkLCBnZW5lKSwgYnkgPSBjKCJnZW5lX2lkIiA9ICJnZW5lX2lkIikpDQp0cG0uZGYgPC0gZGlzdGluY3QodHBtLmRmLCBnZW5lLCAua2VlcF9hbGwgPSBUUlVFKQ0Kcm93bmFtZXModHBtLmRmKSA8LSB0cG0uZGYkZ2VuZQ0KdHBtLmRmIDwtIHN1YnNldCh0cG0uZGYsIHNlbGVjdCA9IC1jKGdlbmVfaWQsIElEX1JFRiwgZ2VuZSkgKQ0KdHBtLmRmIDwtIHRwbS5kZlsgb3JkZXIocm93Lm5hbWVzKHRwbS5kZikpLCAsIGRyb3AgPSBGQUxTRV0NCnRwbS5kZg0KYGBgDQoNClBsb3QgdGhlIHJlc3VsdHMuDQoNCmBgYHtyLCBmaWcuaGVpZ2h0PTMwLCBmaWcud2lkdGg9MTB9DQp0cG0ubWF0cml4IDwtIGFzLm1hdHJpeCh0cG0uZGYpDQpoZWF0bWFwLjIodHBtLm1hdHJpeCwgc3J0Q29sPTM2MCwgY2VsbG5vdGUgPSB0cG0ubWF0cml4LCBkZW5kcm9ncmFtPSJub25lIiwgQ29sdj1GQUxTRSwgUm93dj1GQUxTRSwNCiAgICAgICAgICBjb2w9YnJld2VyLnBhbChuID0gOSwgbmFtZSA9ICJCdVB1IilbNTo5XSwgdHJhY2U9Im5vbmUiLCBrZXkgPSBGQUxTRSwgbHdpZD1jKDAuMSw0KSwgbGhlaT1jKDAuMSw0KSwNCiAgICAgICAgICBjZXhDb2w9MSwgY2V4Um93PTAuNzUsIHN5bW0gPSBUUlVFKQ0KYGBgDQojIyMgRmVycm9wdG9zaXMNCg0KTG9hZCB0aGUgZ2VuZSBzZXQuDQoNCmBgYHtyfQ0KZ2VuZXMgPC0gcmVhZC5jc3YocGFzdGUwKFJDRGRiLCAiRmVycm9wdG9zaXMuY3N2IikpDQpnZW5lcyRnZW5lX2lkIDwtIGNsZWFuaWQoZ2VuZXMkZ2VuZV9pZCkNCmdlbmVzIDwtIGRpc3RpbmN0KGdlbmVzLCBnZW5lX2lkLCAua2VlcF9hbGwgPSBUUlVFKQ0KZ2VuZXMgPC0gc3Vic2V0KGdlbmVzLCBnZW5lX2lkICE9ICIiKQ0KZ2VuZXMNCmBgYA0KDQpHZXQgdGhlIG5vcm1hbGl6ZWQgZXhwcmVzc2lvbiBkYXRhIGZvciB0aGUgZ2VuZXMgaW4gdGhlIGdlbmUgc2V0Lg0KDQpgYGB7cn0NCnRwbS5kZiA8LSBoZGZuLmV4cHJlc3Npb24gJT4lIGRwbHlyOjpmaWx0ZXIoZ2VuZV9pZCAlaW4lIGdlbmVzJGdlbmVfaWQpDQp0cG0uZGYgPC0gbGVmdF9qb2luKHRwbS5kZiwgZ2VuZXMgJT4lIGRwbHlyOjpzZWxlY3QoZ2VuZV9pZCwgZ2VuZSksIGJ5ID0gYygiZ2VuZV9pZCIgPSAiZ2VuZV9pZCIpKQ0KdHBtLmRmIDwtIGRpc3RpbmN0KHRwbS5kZiwgZ2VuZSwgLmtlZXBfYWxsID0gVFJVRSkNCnJvd25hbWVzKHRwbS5kZikgPC0gdHBtLmRmJGdlbmUNCnRwbS5kZiA8LSBzdWJzZXQodHBtLmRmLCBzZWxlY3QgPSAtYyhnZW5lX2lkLCBJRF9SRUYsIGdlbmUpICkNCnRwbS5kZiA8LSB0cG0uZGZbIG9yZGVyKHJvdy5uYW1lcyh0cG0uZGYpKSwgLCBkcm9wID0gRkFMU0VdDQp0cG0uZGYNCmBgYA0KDQpQbG90IHRoZSByZXN1bHRzLg0KDQpgYGB7ciwgZmlnLmhlaWdodD0xNTAsIGZpZy53aWR0aD0xMH0NCnRwbS5tYXRyaXggPC0gYXMubWF0cml4KHRwbS5kZikNCmhlYXRtYXAuMih0cG0ubWF0cml4LCBzcnRDb2w9MzYwLCBjZWxsbm90ZSA9IHRwbS5tYXRyaXgsIGRlbmRyb2dyYW09Im5vbmUiLCBDb2x2PUZBTFNFLCBSb3d2PUZBTFNFLA0KICAgICAgICAgIGNvbD1icmV3ZXIucGFsKG4gPSA5LCBuYW1lID0gIkJ1UHUiKVs1OjldLCB0cmFjZT0ibm9uZSIsIGtleSA9IEZBTFNFLCBsd2lkPWMoMC4xLDQpLCBsaGVpPWMoMC4xLDQpLA0KICAgICAgICAgIGNleENvbD0xLCBjZXhSb3c9MC43NSwgc3ltbSA9IFRSVUUpDQpgYGANCg0KIyMjIFB5cm9wdG9zaXMNCg0KTG9hZCB0aGUgZ2VuZSBzZXQuDQoNCmBgYHtyfQ0KZ2VuZXMgPC0gcmVhZC5jc3YocGFzdGUwKFJDRGRiLCAiUHlyb3B0b3Npcy5jc3YiKSkNCmdlbmVzJGdlbmVfaWQgPC0gY2xlYW5pZChnZW5lcyRnZW5lX2lkKQ0KZ2VuZXMgPC0gZGlzdGluY3QoZ2VuZXMsIGdlbmVfaWQsIC5rZWVwX2FsbCA9IFRSVUUpDQpnZW5lcyA8LSBzdWJzZXQoZ2VuZXMsIGdlbmVfaWQgIT0gIiIpDQpnZW5lcw0KYGBgDQoNCkdldCB0aGUgbm9ybWFsaXplZCBleHByZXNzaW9uIGRhdGEgZm9yIHRoZSBnZW5lcyBpbiB0aGUgZ2VuZSBzZXQuDQoNCmBgYHtyfQ0KdHBtLmRmIDwtIGhkZm4uZXhwcmVzc2lvbiAlPiUgZHBseXI6OmZpbHRlcihnZW5lX2lkICVpbiUgZ2VuZXMkZ2VuZV9pZCkNCnRwbS5kZiA8LSBsZWZ0X2pvaW4odHBtLmRmLCBnZW5lcyAlPiUgZHBseXI6OnNlbGVjdChnZW5lX2lkLCBnZW5lKSwgYnkgPSBjKCJnZW5lX2lkIiA9ICJnZW5lX2lkIikpDQp0cG0uZGYgPC0gZGlzdGluY3QodHBtLmRmLCBnZW5lLCAua2VlcF9hbGwgPSBUUlVFKQ0Kcm93bmFtZXModHBtLmRmKSA8LSB0cG0uZGYkZ2VuZQ0KdHBtLmRmIDwtIHN1YnNldCh0cG0uZGYsIHNlbGVjdCA9IC1jKGdlbmVfaWQsIElEX1JFRiwgZ2VuZSkgKQ0KdHBtLmRmIDwtIHRwbS5kZlsgb3JkZXIocm93Lm5hbWVzKHRwbS5kZikpLCAsIGRyb3AgPSBGQUxTRV0NCnRwbS5kZg0KYGBgDQoNClBsb3QgdGhlIHJlc3VsdHMuDQoNCmBgYHtyLCBmaWcuaGVpZ2h0PTIwLCBmaWcud2lkdGg9MTB9DQp0cG0ubWF0cml4IDwtIGFzLm1hdHJpeCh0cG0uZGYpDQpoZWF0bWFwLjIodHBtLm1hdHJpeCwgc3J0Q29sPTM2MCwgY2VsbG5vdGUgPSB0cG0ubWF0cml4LCBkZW5kcm9ncmFtPSJub25lIiwgQ29sdj1GQUxTRSwgUm93dj1GQUxTRSwNCiAgICAgICAgICBjb2w9YnJld2VyLnBhbChuID0gOSwgbmFtZSA9ICJCdVB1IilbNTo5XSwgdHJhY2U9Im5vbmUiLCBrZXkgPSBGQUxTRSwgbHdpZD1jKDAuMSw0KSwgbGhlaT1jKDAuMSw0KSwNCiAgICAgICAgICBjZXhDb2w9MSwgY2V4Um93PTAuNzUsIHN5bW0gPSBUUlVFKQ0KYGBg